Introduction to ML
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)
Overview
DBSCANは、「density-based spatial clustering of applications with noise」(密度に基づくノイズあり空間クラスタリング)の略語です。DBSCANの主な利点は、ユーザがクラスタ数を先験的に与える必要がないことと、どのクラスタにも属さない点を判別できることです。DBSCANは凝集型クラスタリングよりもk-meansよりも遅いですが、比較的大きいデータセットにも適用できます。
Coding
合成データセットにDBSCANを適用する
from sklearn.datasets import make_blobs
from sklearn.cluster import DBSCAN
X, y = make_blobs(random_state=0, n_samples=12)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X)
print("Cluster memberships:\n{}".format(clusters))
--------------------------------------------------------------------------
Cluster memberships:
[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
--------------------------------------------------------------------------
結果を見ると、すべてのデータポイントがノイズを表すラベル-1になっています。これは、epsとmin_samplesのデフォルト設定が、小さいデータセットに適していないからです。epsとmin_samplesを様々な値に設定してクラスタリングすると下のような結果になります。
mglearn.plots.plot_dbscan()
--------------------------------------------------------------------------
min_samples: 2 eps: 1.000000 cluster: [-1 0 0 -1 0 -1 1 1 0 1 -1 -1]
min_samples: 2 eps: 1.500000 cluster: [0 1 1 1 1 0 2 2 1 2 2 0]
min_samples: 2 eps: 2.000000 cluster: [0 1 1 1 1 0 0 0 1 0 0 0]
min_samples: 2 eps: 3.000000 cluster: [0 0 0 0 0 0 0 0 0 0 0 0]
min_samples: 3 eps: 1.000000 cluster: [-1 0 0 -1 0 -1 1 1 0 1 -1 -1]
min_samples: 3 eps: 1.500000 cluster: [0 1 1 1 1 0 2 2 1 2 2 0]
min_samples: 3 eps: 2.000000 cluster: [0 1 1 1 1 0 0 0 1 0 0 0]
min_samples: 3 eps: 3.000000 cluster: [0 0 0 0 0 0 0 0 0 0 0 0]
min_samples: 5 eps: 1.000000 cluster: [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
min_samples: 5 eps: 1.500000 cluster: [-1 0 0 0 0 -1 -1 -1 0 -1 -1 -1]
min_samples: 5 eps: 2.000000 cluster: [-1 0 0 0 0 -1 -1 -1 0 -1 -1 -1]
min_samples: 5 eps: 3.000000 cluster: [0 0 0 0 0 0 0 0 0 0 0 0]
--------------------------------------------------------------------------
epsを増やすと、より多くの点がクラスタに含まれるようになります。こうするとクラスタが大きくなりますが、複数のクラスタが併合されることにもなります。min_samplesを増やすと、コアポイントになるデータポイントが少なくなり、より多くのデータポイントがノイズになります。
良いepsの値を見つけるには、スケール変換してからのほうが容易であることが多いです。スケール変換を行うと、すべての特徴量が同じ範囲になることが保証されているからです。
two_moonsデータセットにStandardScalerでスケール変換してDBSCANを適用する
import matplotlib.pyplot as plt
import mglearn
from sklearn.datasets import make_moons
from sklearn.preprocessing import StandardScaler
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
# データを平均0分散1にスケール変換
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X_scaled)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=clusters, cmap=mglearn.cm2, s=60)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")